package com.ease.juc.utils;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author: chenhs
 * @date: Created in 15:59 2021/10/17
 **/
public class CounterCAS implements Counter {

    volatile int i = 0;

    static long filedOffset = 0L;

    static Unsafe unsafe;


    static {

        try {
            //反射获取对象
            Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
            Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);

            //获取到类的属性
            Field field = CounterCAS.class.getDeclaredField("i");

            //获取到指定类的指定属性在内存中的偏移量；操作系统中皆文件，内存中对象本质是01010101010，也是一个文件
            filedOffset = unsafe.objectFieldOffset(field);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void incr() {
        //内存当前值
        int current;
        //内存结果值
        int result;

        do {
            current = i;
            result = current + 1;
            /**
             * 比较增量
             *
             *
             * 比较obj的offset处内存位置中的值和期望的值，如果相同则更新。此更新是不可中断的。
             *
             * @param obj 需要更新的对象
             * @param offset obj中整形field的偏移量
             * @param expect 希望field中存在的值
             * @param update 如果期望值expect与field的当前值相同，设置field的值这个新值
             *
             * return 如果field的值被更新则返回true
             */
        } while (!unsafe.compareAndSwapInt(this, filedOffset, current, result));
    }

    @Override
    public void desc() {
        i--;
    }

    @Override
    public Integer getResult() {
        return i;
    }
}
